package wxdb.ui;

import javax.swing.*;
import wxdb.record.*;
import javax.swing.table.*;
import javax.swing.tree.*;

import wxdb.metadata.*;
import java.util.*;
import java.awt.*;
import wxdb.parse.*;
import wxdb.parse.absyn.*;

import java.awt.event.*;

public class Management extends JFrame{

	private JMenuBar bar = new JMenuBar();
	
/* 
 * We need to make a buffer here,
 * the buffer can be an array or a list or whatever,
 * the buffer is used to manage the memory: how many record should be stored in.
 * I'm not sure what should be done here, because it's beyond the GUI design
 */
	
	private JMenu menuStart = new JMenu("Start");
	private JMenu menuEdit = new JMenu("Edit");
	private JMenu menuHelp = new JMenu("Help");
	
	private JMenuItem menuStartSetting = new JMenuItem("Setting");
	private JMenuItem menuCmd = new JMenuItem("Command");
	private JMenuItem menuStartQuit = new JMenuItem("Exit");	
	private JMenuItem modifyRecord = new JMenuItem("modifyRecord");
	private JMenuItem menuHelpAbout = new JMenuItem("About");
	
	private JButton refresh = new JButton("Refresh");
	
	private JTree databaseTree;		/* initial in function "buildDatabaseTree" */
	private JTable databaseTable = new JTable(); 	/* initial in function "buildDatabaseTable" */
	
	private JPanel pane = new JPanel();
	private String db = "";
	private String currentbl = "";
	
	private void initconter(){

		menuStart.add(menuStartSetting);
		menuStart.add(menuCmd);
		menuStart.add(menuStartQuit);
		menuHelp.add(menuHelpAbout);
		menuEdit.add(modifyRecord);
		
		bar.add(menuStart);
		bar.add(menuEdit);
		bar.add(menuHelp);
	}
	
	
	void buildConstraints(GridBagConstraints gbc,int gx, int gy, int gw, int gh, int wx, int wy){
		gbc.gridx = gx;			
		gbc.gridy = gy;			
		gbc.gridwidth = gw;		
		gbc.gridheight = gh;	
		gbc.weightx = wx;		
		gbc.weighty = wy;		
	}
	
	
	private void setMyPane(){

		pane.setLayout(null);
		
		buildDatabaseTree();
//    	buildDatabaseTable();
		
		JScrollPane treePane = new JScrollPane(databaseTree);
		treePane.setBounds(10,5,160,708);
		pane.add(treePane);
		
		JScrollPane tablePane = new JScrollPane(databaseTable);
		tablePane.setBounds(170, 0, 1000, 713);
		pane.add(tablePane);
		
		refresh.setBounds(1170,0,100,30);
		pane.add(refresh);

		
		initconter();
		
		setJMenuBar(bar);
		setContentPane(pane);
	}
	
	private void buildDatabaseTree(){
		
		DefaultMutableTreeNode[] nodes = new DefaultMutableTreeNode[1];
		nodes[0] = new DefaultMutableTreeNode(db);
		DbInfo dbinfo = DbInfoMgr.getMeta(Global.currentdb);
		ArrayList<String> tbls = dbinfo.getTables();
		for(String tb : tbls){
			nodes[0].add(new DefaultMutableTreeNode(tb));
		}

		databaseTree = new JTree(nodes[0]);
	}
	
	private int totoalRows = 10;;  
	private int totalColumns = 10;
	private String[][] myObjs = new String[totoalRows][totalColumns];
	
	void refreshTable(){
		try{
			String cmd = "SELECT * FROM "+currentbl;
			Global.REFRESHTABLE = true;
			parser p = new parser(cmd);
			p.parse();
			Object e = p.parseResult;
			Global.planner().excuteQueryPlan((QryExp)e);
			if(Global.queryFields.size()==0)
				return;
			totoalRows = Global.queryResult.size()/Global.queryFields.size();
			totalColumns = Global.queryFields.size();
			
			myObjs = new String[totoalRows][totalColumns];
			
			TableModel dataModel = new AbstractTableModel(){   
				public int getColumnCount(){
					return totalColumns;   
				}
				public int getRowCount(){   
					return myObjs != null ? myObjs.length : 0;   
				}
				public String getColumnName(int columnIndex){   
					return  Global.queryFields.get(columnIndex).toString();   
				}   
				public Object getValueAt(int row, int col){
					if(Global.queryFields.size()==0)
						return null;
					int index = col*Global.queryResult.size()/Global.queryFields.size()+row;
					myObjs[row][col] = Global.queryResult.get(index).toString(); 		
					return myObjs[row][col];
				}   
			};
			this.databaseTable.setModel(dataModel);   
		}catch(Exception   ex)   {   
			ex.printStackTrace();
		}   
	}

	public void addTreeNode(String tblname){
	    DefaultMutableTreeNode parentNode=null;
	    DefaultMutableTreeNode newNode=new DefaultMutableTreeNode(tblname);
	    newNode.setAllowsChildren(true);
	    TreeNode root = (TreeNode)databaseTree.getModel().getRoot();
	    parentNode=(DefaultMutableTreeNode)root;
	    DefaultTreeModel treeModel = (DefaultTreeModel)databaseTree.getModel();
	    treeModel.insertNodeInto(newNode,parentNode,parentNode.getChildCount());
	    databaseTree.scrollPathToVisible(new TreePath(newNode.getPath()));
	}
	
	private void initListener(){
		ActListener actListener = new ActListener();
		menuStartSetting.addActionListener(actListener);
		menuStartQuit.addActionListener(actListener);
		menuCmd.addActionListener(actListener);
		menuHelpAbout.addActionListener(actListener);
		modifyRecord.addActionListener(actListener);
		refresh.addActionListener(actListener);
		databaseTree.addMouseListener(new MouseHandle());
	}
	
	class MouseHandle extends MouseAdapter {	
		public void mousePressed(MouseEvent e){
			int selRow = databaseTree.getRowForLocation(e.getX(), e.getY());
	        TreePath selPath = databaseTree.getPathForLocation(e.getX(), e.getY());
	        if(selRow != -1) {
	            if(e.getClickCount() == 2) {
	           	 	currentbl = selPath.getLastPathComponent().toString();
	           	 	refreshTable();
	            }
	        }
		}
	}

	class ActListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			if(e.getSource() == menuStartSetting)
				getSetting();
			if(e.getSource() == menuStartQuit)
				System.exit(0);
			if(e.getSource() == menuHelpAbout)
				JOptionPane.showMessageDialog(null,Global.VERSION, "About DBMS", JOptionPane.INFORMATION_MESSAGE);
			if(e.getSource() == menuCmd)
				getCmd();
			if(e.getSource() == modifyRecord)
				modifyRecord();
			if(e.getSource() == refresh)
				refreshTable();
		}
	}
	
	private void getCmd(){
		UserIn uin = new UserIn();
	}
	
	private void getSetting(){
		Setting st = new Setting();
	}
	
	private void getNextPage(){
		System.out.println("getNextPage");
	}
	
	private void modifyRecord(){
		ModifyRecord mr = new ModifyRecord();
	}
	
	public Management(String dbName){
		super(Global.VERSION);
		db = dbName;
		Global.currentdb = Global.findDBID(dbName);
		setSize(800,700);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setExtendedState(JFrame.MAXIMIZED_BOTH);
		setMyPane();
		initListener();
		setVisible(true);
		setResizable(false);
	}
}
